package com.cn.client.remplance;

import com.cn.client.AllocateMessageQueueStrategy;
import com.cn.common.MessageQueue;
import com.cn.common.consistenthash.ConsistentHash;
import com.cn.common.consistenthash.Node;
import com.cn.common.consistenthash.VirtualNode;

import java.util.ArrayList;
import java.util.List;

/**
 * hash一致性分配
 */
public class AllocateMessageQueueConsistentHash implements AllocateMessageQueueStrategy {

    @Override
    public List<MessageQueue> allocate(String group, List<MessageQueue> mqs, List<String> cidAll, String clientId) {

        List<Node> pyhNodes = new ArrayList<>();
        for (String cid : cidAll) {
            pyhNodes.add(new ClientNode(cid));
        }

        ConsistentHash consistentHash = new ConsistentHash(10, pyhNodes);

        List<MessageQueue> mqAll = new ArrayList<>();
        for (MessageQueue mq : mqs) {
            VirtualNode virtualNode = consistentHash.route(mq.toString());
            if (virtualNode != null && virtualNode.getPyhsicalNode().getKey().equals(clientId)) {
                mqAll.add(mq);
            }
        }
        return mqAll;
    }

    @Override
    public String getName() {
        return "HASH一致";
    }


    class ClientNode implements Node {

        private String clientId;

        public ClientNode(String clientId) {
            this.clientId = clientId;
        }

        @Override
        public String getKey() {
            return this.clientId;
        }

        @Override
        public String toString() {
            return "ClientNode{" +
                    "clientId='" + clientId + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) {
        List<MessageQueue> mq = new ArrayList<>();
        mq.add(new MessageQueue().setQueueId(0).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(1).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(3).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(4).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(5).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(6).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(7).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(8).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(9).setTopic("top1"));
        mq.add(new MessageQueue().setQueueId(10).setTopic("top1"));


        List<String> cids = new ArrayList<>();
        cids.add("client_1");
        cids.add("client_2");
        cids.add("client_3");
        cids.add("client_4");
        cids.add("client_5");

        AllocateMessageQueueConsistentHash t = new AllocateMessageQueueConsistentHash();

        List<MessageQueue> l = t.allocate(null, mq, cids, "client_5");
        for (MessageQueue messageQueue : l) {
            System.out.println(messageQueue);
        }

    }

}
